// Import MD5 function from a utility library
import * as Crypto from 'crypto-js'; // Adjust the import path as needed

const host = 'https://demo.weila.hk';
const weila_appid = "102036"
const weila_appkey = "b3c658bd2e637c65efb134fb381d4a18" // 微喇appkey

// 定义通用的请求参数类型
export interface CommonQueryParams {
    appid: string;
    et: string;
    sign: string;
}

// 定义各个接口的请求体类型
export interface GetAccountByPhoneBody {
    wx: {
        appid: string;
        openid: string;
        unionid: string;
        sessionkey: string;
    };
    phone: string;
    verifycode: string;
}

export interface GetAccountByCodeBody {
    wx: {
        appid: string;
        openid: string;
        unionid: string;
        sessionkey: string;
    };
    code: string;
}

export interface Code2SessionBody {
    wx: {
        appid: string;
    };
    jscode: string;
}

export interface SendPhoneVerifyCodeBody {
    wx: {
        appid: string;
        openid: string;
        unionid: string;
        sessionkey: string;
    };
    phone: string;
    countrycode: string;
}

// Merchant API interfaces
export interface GetNearbyMerchantBody {
    loc: {
        lat: number;
        lon: number;
    };
}

export interface GetFollowMerchantBody {
    // Empty body
}

export interface FollowMerchantBody {
    mid: number;
}

export interface UnfollowMerchantBody {
    mid: number;
}

export interface GetMerchantBody {
    mid: number;
}

// Common merchant API query params with token
export interface AuthQueryParams extends CommonQueryParams {
    token: string;
}

// 封装请求函数
function request<T>(
    url: string,
    method: string,
    queryParams: CommonQueryParams,
    data: any
): Promise<T> {
    return new Promise((resolve, reject) => {
        const queryString = Object.keys(queryParams)
            .map((key) => `${key}=${queryParams[key as keyof CommonQueryParams]}`)
            .join('&');
        const fullUrl = `${url}?${queryString}`;

        wx.request({
            url: fullUrl,
            method,
            data,
            header: {
                'Content-Type': 'application/json',
            },
            success: (res) => {
                if (res.statusCode === 200) {
                    resolve(res.data as T);
                } else {
                    reject(new Error(`请求失败，状态码: ${res.statusCode}`));
                }
            },
            fail: (err) => {
                reject(new Error(`请求出错: ${err.errMsg}`));
            },
        });
    });
}

// 手机验证码获取账号密码
export async function getAccountByPhone(
    body: GetAccountByPhoneBody
) {
    const url = `${host}/v2/wechat/auth/get-account-by-phone`;
    let queryParams: CommonQueryParams;
    queryParams = {
        appid: weila_appid, // 微喇appid
        et: Math.floor(Date.now() / 1000).toString(), // 更新时间戳,秒
        sign: '', // 签名
    };
    queryParams.sign = generateSign(queryParams); // 生成签名
    return request<any>(url, 'POST', queryParams, body);
}

// 一键获取账号密码
export async function getAccountByCode(
    body: GetAccountByCodeBody
) {
    const url = `${host}/v2/wechat/auth/get-account-by-code`;
    let queryParams: CommonQueryParams;
    queryParams = {
        appid: weila_appid, // 微喇appid
        et: Math.floor(Date.now() / 1000).toString(), // 更新时间戳,秒
        sign: '', // 签名
    };
    queryParams.sign = generateSign(queryParams); // 生成签名

    console.log("getAccountByCode", queryParams, body);
    
    return request<any>(url, 'POST', queryParams, body);
}

// 获取session
export async function code2session(
    body: Code2SessionBody
) {
    const url = `${host}/v2/wechat/auth/code2session`;
    let queryParams: CommonQueryParams;
    queryParams = {
        appid: weila_appid, // 小程序appid
        et: Math.floor(Date.now() / 1000).toString(), // 更新时间戳,秒
        sign: '', // 签名
    };
    queryParams.sign = generateSign(queryParams); // 生成签名
    return request<any>(url, 'POST', queryParams, body);
}

// 发送手机号验证码
export async function sendPhoneVerifyCode(
    body: SendPhoneVerifyCodeBody
) {
    const url = `${host}/v2/wechat/auth/send-phone-verifycode`;
    let queryParams: CommonQueryParams;
    queryParams = {
        appid: weila_appid, // 小程序appid
        et: Math.floor(Date.now() / 1000).toString(), // 更新时间戳,秒
        sign: '', // 签名
    };
    queryParams.sign = generateSign(queryParams); // 生成签名
    return request<any>(url, 'POST', queryParams, body);
}

// 获取附近的商户
export async function getNearbyMerchant(
    token: string,
    body: GetNearbyMerchantBody
) {
    const url = `${host}/v2/life/mer/get-nearby-merchant`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token
    };
    queryParams.sign = generateSign(queryParams);
    return request<any>(url, 'POST', queryParams, body);
}

// 获取关注的商户
export async function getFollowMerchant(
    token: string,
    body: GetFollowMerchantBody = {}
) {
    const url = `${host}/v2/life/mer/get-follow-merchant`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token
    };
    queryParams.sign = generateSign(queryParams);
    return request<any>(url, 'POST', queryParams, body);
}

// 关注商户
export async function followMerchant(
    token: string,
    body: FollowMerchantBody
) {
    const url = `${host}/v2/life/mer/follow-merchant`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token
    };
    queryParams.sign = generateSign(queryParams);
    return request<any>(url, 'POST', queryParams, body);
}

// It looks like token is not required for unfollowMerchant based on the API documentation
// 取消关注商户
export async function unfollowMerchant(
    token: string,
    body: UnfollowMerchantBody
) {
    const url = `${host}/v2/life/mer/unfollow-merchant`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token,
    };
    queryParams.sign = generateSign(queryParams);
    return request<any>(url, 'POST', queryParams, body);
}

// 获取商户详情
export async function getMerchant(
    token: string,
    body: GetMerchantBody
) {
    const url = `${host}/v2/life/mer/get-merchant`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token
    };
    queryParams.sign = generateSign(queryParams);
    return request<any>(url, 'POST', queryParams, body);
}

// 上传文件
export async function uploadFile(
    token: string,
    filePath: string,
    fileName: string,
    onProgressUpdateCallback?: (progress: number) => void // Optional callback for progress updates
): Promise<any> {
    let url = `${host}/v2/common/upload-file`;
    let queryParams: AuthQueryParams = {
        appid: weila_appid,
        et: Math.floor(Date.now() / 1000).toString(),
        sign: '',
        token: token
    };
    queryParams.sign = generateSign(queryParams);

    url = `${url}?${Object.keys(queryParams)
        .map((key) => `${key}=${queryParams[key as keyof AuthQueryParams]}`)
        .join('&')}`;

    console.log("uploadFile", url, filePath, fileName);
    
    return new Promise((resolve, reject) => {
        const uploadTask = wx.uploadFile({
            url: url,
            filePath: filePath,
            name: fileName,
            header: {
                'Expect': undefined,
                'Content-Type': 'multipart/form-data',
            },
            success: (res) => {
                console.log('Upload success:', res);
                
                if (res.statusCode === 200) {
                    resolve(res.data);
                } else {
                    reject(new Error(`上传失败，状态码: ${res.statusCode}`));
                }
            },
            fail: (err) => {
                reject(new Error(`上传出错: ${err.errMsg}`));
            },
        });

        // Add onProgressUpdate listener
        if (onProgressUpdateCallback) {
            const progressListener = (res: WechatMiniprogram.UploadTaskOnProgressUpdateListenerResult) => {
                console.log('Upload progress:', res.progress);
                if (onProgressUpdateCallback) {
                    onProgressUpdateCallback(res.progress); // Call the callback with the progress value

                    if (res.progress === 100) {
                        console.log('Upload complete!');
                        // offProgressUpdate listener if needed
                        uploadTask.offProgressUpdate(progressListener);
                    }
                }
            };

            uploadTask.onProgressUpdate(progressListener);
        }
    });
}

/**
 * Generate a sign from CommonQueryParams
 * @param params The CommonQueryParams object containing et and appid
 * @returns An 8-byte substring from the MD5 hash
 */
export function generateSign(params: CommonQueryParams): string {
  // Format et and appid into a string
  const strToHash = `${params.et}${weila_appkey}`;

  // Calculate MD5 hash of the string
  const md5Hash = Crypto.MD5(strToHash, {})

 console.log("strToHash", strToHash);
 console.log("md5Hash", md5Hash.toString());

  // Return substring from position 12 to 20 (8 bytes)
  return md5Hash.toString().substring(12, 20);
}


